<?php

namespace wechat\wxpay;

include __DIR__ . '/lib/WxPayApi.php';

/**
 *
 * JSAPI支付实现类
 * 生成jsapi支付js接口所需的参数、生成获取共享收货地址所需的参数
 * @author menglingyue
 * GetJsApiParameters   获取支付参数
 * OrderQueryResult     订单查询
 * OrderRefundResult    订单退款
 * OrderRefundQuery     订单退款查询
 */
class JsApiPay
{
    /**
     * 统一下单
     * @param array $params
     * @param string $prepay_id 预支付订单号 如需发送小程序模板消息传入
     * @return array
     * @throws \WxPayException
     */
    public function SetUnifiedOrder($params = array(), &$prepay_id = '')
    {
        $notify_url = array_key_exists('notify_url', $params) ? $params['notify_url'] : \WxPayConfig::NOTIFY_URL;
        $input = new \WxPayUnifiedOrder();
        $input->SetBody($params['body']); // 商品描述
        $input->SetAttach("");
        $input->SetOut_trade_no($params['out_trade_no']); // 订单ID
        $input->SetTotal_fee($params['price']);  // 订单金额
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 1200));
        $input->SetTrade_type("JSAPI");
        $input->SetNotify_url($notify_url);
        $input->SetOpenid($params['openid']);
        $order = \WxPayApi::unifiedOrder($input);
        $prepay_id = array_key_exists('prepay_id', $order) ? $order['prepay_id'] : '';
        $jsApiParameters = $this->GetJsApiParameters($order);
        return $jsApiParameters;
    }

    /**
     * 获取jsapi支付的参数
     * @param $UnifiedOrderResult array 统一支付接口返回的数据
     * @return array json数据，可直接填入js函数作为参数
     * @throws \WxPayException
     */
    public function GetJsApiParameters($UnifiedOrderResult)
    {
        if (!array_key_exists("appid", $UnifiedOrderResult)
            || !array_key_exists("prepay_id", $UnifiedOrderResult)
            || $UnifiedOrderResult['prepay_id'] == "") {
            throw new \WxPayException("参数错误");
        }
        $jsapi = new \WxPayJsApiPay();
        $jsapi->SetAppid($UnifiedOrderResult["appid"]);
        $timeStamp = time();
        $jsapi->SetTimeStamp("$timeStamp");
        $jsapi->SetNonceStr(\WxPayApi::getNonceStr());
        $jsapi->SetPackage("prepay_id=" . $UnifiedOrderResult['prepay_id']);
        $jsapi->SetSignType("MD5");
        $jsapi->SetPaySign($jsapi->MakeSign());
        $parameters = $jsapi->GetValues();
        return $parameters;
    }

    /**
     * 订单查询
     * @param array $params
     * @return array|bool
     * @throws \WxPayException
     */
    public function OrderQueryResult($params = array())
    {
        $input = new \WxPayOrderQuery();
        if (isset($params['transaction_id']) && $params['transaction_id']) {
            $input->SetTransaction_id($params['transaction_id']);
        } else if (isset($params['out_trade_no']) && $params['out_trade_no']) {
            $input->SetOut_trade_no($params['out_trade_no']);
        } else {
            return false;
        }
        return \WxPayApi::orderQuery($input);
    }

    /**
     * 订单退款
     * @param array $params transaction_id:微信订单号 out_trade_no:商户订单号 二选一
     * @return array|bool
     * @throws \WxPayException
     */
    public function OrderRefundResult($params = array())
    {
        $input = new \WxPayRefund();
        if (isset($params['transaction_id']) && $params['transaction_id']) {
            $refund = 'TK' . $params['transaction_id'] . rand(1, 10);
            $input->SetTransaction_id($params['transaction_id']);
        } else if (isset($params['out_trade_no']) && $params['out_trade_no']) {
            $refund = 'TK' . $params['out_trade_no'];
            $input->SetOut_trade_no($params['out_trade_no']);
        } else {
            return false;
        }
        $input->SetTotal_fee($params['total_fee'] * 100);
        $input->SetRefund_fee($params['refund_fee'] * 100);
        $input->SetOut_refund_no($params['out_refund_no'] ?? $refund);
        $input->SetOp_user_id(\WxPayConfig::$mchid);
        return \WxPayApi::refund($input);
    }

    /*
	 * 
	 * 订单退款查询
     * $params transaction_id:微信订单号 out_trade_no:商户订单号
	 */
    /**
     * @param array $params transaction_id:微信订单号 out_trade_no:商户订单号 二选一
     * @return array|bool
     * @throws \WxPayException
     */
    public function OrderRefundQuery($params = array())
    {
        $input = new \WxPayRefundQuery();
        if (isset($params['transaction_id']) && $params['transaction_id']) {
            $input->SetTransaction_id($params['transaction_id']);
        } else if (isset($params['out_trade_no']) && $params['out_trade_no']) {
            $input->SetOut_trade_no($params['out_trade_no']);
        } else {
            return false;
        }
        return \WxPayApi::refundQuery($input);
    }

    /**
     * 拼接签名字符串
     * @param array $urlObj
     * @return string 返回已经拼接好的字符串
     */
    protected function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v) {
            if ($k != "sign") {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
}